// mouse.cpp
// 25 September 2011
// Purpose: definitions for Mouse class       

#include "mouse.h"
#include <iostream>
using std::cout;
using std::endl;

Mouse::Mouse(const Map & m):				// Default Constructor. Assigns mouse to starting position of map
coord(m.getStart()), _trail(new int[m.getH()])
{
	for(int ii=0; ii<m.getH(); ii++)			
		_trail[ii]=0;
	
}

bool Mouse::solve(const Map & m)					//solves map, prints out each movement through the map.
{
	int height=m.getH();
	int mask=1<<coord._x;
	int index=coord._y;
	Coordinate finish=m.getFinish();
	int * maze=new int [m.getH()]; 
	maze=m.getMap();
	bool north=false;
	bool south=false;
	bool east=false;
	bool west=false;
	int intersection;
	
	while(index!=0 || mask!=1)
	{
		if(left(maze,index,mask) && right(maze,index,mask) && down(maze,index,mask,height))
		{
			intersection=mask;
		}
		else if(left(maze,index,mask) && right(maze,index,mask) && up(maze,index,mask))
		{
			intersection=mask;
		}
		else if(left(maze,index,mask) && down(maze,index,mask,height) && up(maze,index,mask))
		{
			intersection=mask;
		}
		else if(right(maze,index,mask) && down(maze,index,mask,height) && up(maze,index,mask))
		{
			intersection=mask;
		}
		if(mask!=1<<19)
		{
			if(left(maze,index,mask)==false && right(maze,index,mask)==false && down(maze,index,mask,height)==false && north==false)
			{
				mask=intersection;
				if(south)
					north=true;
			}
			else if(left(maze,index,mask)==false && right(maze,index,mask)==false && up(maze,index,mask)==false && south==false)
			{
				mask=intersection;
				if(north)
					south=true;
			}
			else if(left(maze,index,mask)==false && down(maze,index,mask,height)==false && up(maze,index,mask)==false && east==false)
			{
				mask=intersection;
				if(west)
					east=true;
			}
			else if(right(maze,index,mask)==false && down(maze,index,mask,height)==false && up(maze,index,mask)==false && west==false)
			{
				mask=intersection;
				if(east)
					west=true;
			}
		}
		if(left(maze,index,mask) && east==false)
		{
			moveLeft(maze,index,mask);
			east=false;
			west=true;
			north=false;
			south=false;
			cout<<"l";
		}
		else if(right(maze,index,mask) && west==false)
		{
			moveRight(maze,index,mask);
			east=true;
			west=false;
			north=false;
			south=false;
			cout<<"r";
		}
		else if(down(maze,index,mask,height) && north==false)
		{
			moveDown(maze,index,mask,height);
			east=false;
			west=false;
			north=false;
			south=true;
			cout<<"d";
		}
		else if(up(maze,index,mask) && south==false)
		{
			moveUp(maze,index,mask);
			east=false;
			west=false;
			north=true;
			south=false;
			cout<<"u";
		}

	}
	return true;

}	
	
void Mouse::displayMap(const Map & m)           // Prints map and mouse location to cout
{
	cout<<endl;
	for(int y=0;y<m.getH();y++)
    {
            for(int x=32;x>=0;x--)
            {
                    int temp = _trail[y];
                    temp= temp >> x;
                    temp= temp&1;
                    if(temp==1)
                    {
						 cout<<1;
                    }
                    else
                    {
                         cout<<0;
                    }
            }
            cout<<endl;
    }
}

int Mouse::getX() const       // Returns _x position of mouse in map
{
	return 5;
}

int Mouse::getY() const       // Returns _y position of mouse in map
{
	return 5;
}

bool Mouse::moveLeft(const int maze[], const int index, int & mask)                // Moves left and returns if the action was successful
{
	if((mask<<1)>=(1<<19))
		return false;
	else if(maze[index] & mask<<1)
		return false;
	else
		mask=mask<<1;
		_trail[index] = _trail[index] | mask;
		return true;
}

bool Mouse::moveRight(const int maze[], const int index, int & mask)               // Moves right and returns if the action was successful
{
	if(maze[index] & mask>>1)
		return false;
	else
		mask=mask>>1;
		_trail[index] = _trail[index] | mask;
		return true;
}

bool Mouse::moveUp(const int maze[], int & index, const int mask)                  // Moves up and returns if the action was successful
{
	if((index-1)<0)
		return false;
	else if(maze[index-1] & mask)
		return false;
	else
	{
		--index;
		_trail[index] = _trail[index] | mask;
		return true;
	}
}

bool Mouse::moveDown(const int maze[], int & index, const int mask, const int height)                // Moves down and returns if the action was successful
{
	if((index+1)>height)
		return false;
	else if(maze[index+1] & mask)
		return false;
	else
	{
		++index;
		_trail[index] = _trail[index] | mask;
		return true;
	}
}

bool Mouse::left(const int maze[], const int index, const int mask)
{
	if((mask<<1)>=(1<<19))
		return false;
	else if(maze[index] & mask<<1)
		return false;
	else
		return true;
}
bool Mouse::right(const int maze[], const int index, const int mask)
{
	if((mask>>1)<1)
		return false;
	else if(maze[index] & mask>>1)
		return false;
	else
		return true;
}
bool Mouse::up(const int maze[], const int index, const int mask)
{
	if((index-1)<0)
		return false;
	else if(maze[index-1] & mask)
		return false;
	else
		return true;
}
bool Mouse::down(const int maze[], const int index, const int mask, const int height)
{
	if((index+1)>height)
		return false;
	else if(maze[index+1] & mask)
		return false;
	else
		return true;
}